/*
 * Copyright (c) 2018.
 * 北京九思金信科技有限公司对该文件内容保留所有权利。
 * 未经许可，不得私自拷贝、传播、发布、引用该文件内容，违者将被追究法律责任。
 */

import {RESIDENT_IDENTITY_CARD,CREDIT_CODE,ORGANIZATIONAL_CODE} from './constant'



//根据客户名称或证件号码查询是否已存在
export function existsCustNo(_this, rule, value, callback) {
  _this.$http.get('/joys-rest/lss-customer/custInfo/byidentity', {
      params: {
        filter: value
      }
    }
  ).then(resp => {
    if (resp.body && resp.body != null) {
      callback(new Error("证件号码已存在，请重新输入"))
    } else {
      callback()
    }
  }, resp => {
    callback()
  })
}
//根据客户名称或证件号码查询是否已存在
export function existsCustName(_this, rule, value, callback) {
  _this.$http.get('/joys-rest/lss-customer/custInfo/byidentity', {
      params: {
        filter: value
      }
    }
  ).then(resp => {
    if (resp.body && resp.body != null) {
      callback(new Error("客户已存在，请重新输入"))
    } else {
      callback()
    }
  }, resp => {
    callback()
  })
}

/**
 * 验证手机号码
 *
 * 移动号码段:139、138、137、136、135、134、150、151、152、157、158、159、182、183、187、188、147
 * 联通号码段:130、131、132、136、185、186、145
 * 电信号码段:133、153、180、189
 */
//手机号码格式判断
export function mobileFormat(value) {
  if (value.length == 11) {
    var regex = "^(13[0-9]|14[1|4|5|6|7|8|9]|15[0|1|2|3|5|6|7|8|9]|16[6]|17[0|1|3|5|6|7|8]|18[0|1|2|3|5|6|7|8|9]|19[8|9])\\d{8}$"
    var regExp = new RegExp(regex)
    return regExp.test(value)
  }
}

//邮编格式判断
export function postCode(value){
  let reg =/^[0-9]{6}$/
  let regExp = new RegExp(reg)
   return regExp.test(value)
}

//邮箱格式判断
export function mailFormat(value) {
  var regex = "^\\w+([-+.]\\w+)*@\\w+([-.]\\w+)*\\.\\w+([-.]\\w+)*$"
  var regExp = new RegExp(regex)
  return regExp.test(value)
}

//个人证件类型对应证件号码格式判断
export function identityFormat(type, value) {
  //身份证
  if (RESIDENT_IDENTITY_CARD == type && !IdentityCodeValid(value)) {
    return false
  }
  return true
}

//单位证件类型对应证件号码格式判断
export function identityCorpFormat(type, value) {
  //单位客户的中征码与个人客户身份证码号对应的数字相同，且中征码不做校验
  //组织结构代码
  if (ORGANIZATIONAL_CODE == type && !isValidOrgCode(value)) {
    return false
  }
  //社会统一信用代码
  if (CREDIT_CODE == type && !CheckSocialCreditCode(value)) {
    return false
  }
  return true
}


//身份证号码格式判断
/*
根据〖中华人民共和国国家标准 GB 11643-1999〗中有关公民身份号码的规定，公民身份号码是特征组合码，由十七位数字本体码和一位数字校验码组成。排列顺序从左至右依次为：六位数字地址码，八位数字出生日期码，三位数字顺序码和一位数字校验码。
    地址码表示编码对象常住户口所在县(市、旗、区)的行政区划代码。
    出生日期码表示编码对象出生的年、月、日，其中年份用四位数字表示，年、月、日之间不用分隔符。
    顺序码表示同一地址码所标识的区域范围内，对同年、月、日出生的人员编定的顺序号。顺序码的奇数分给男性，偶数分给女性。
    校验码是根据前面十七位数字码，按照ISO 7064:1983.MOD 11-2校验码计算出来的检验码。

出生日期计算方法。
    15位的身份证编码首先把出生年扩展为4位，简单的就是增加一个19或18,这样就包含了所有1800-1999年出生的人;
    2000年后出生的肯定都是18位的了没有这个烦恼，至于1800年前出生的,那啥那时应该还没身份证号这个东东，⊙﹏⊙b汗...
下面是正则表达式:
 出生日期1800-2099  (18|19|20)?\d{2}(0[1-9]|1[12])(0[1-9]|[12]\d|3[01])
 身份证正则表达式    /^\d{6}(18|19|20)?\d{2}(0[1-9]|1[012])(0[1-9]|[12]\d|3[01])\d{3}(\d|X)$/i
 15位校验规则 6位地址编码+6位出生日期+3位顺序号
 18位校验规则 6位地址编码+8位出生日期+3位顺序号+1位校验位

 校验位规则     公式:∑(ai×Wi)(mod 11)……………………………………(1)
                公式(1)中：
                i----表示号码字符从由至左包括校验码在内的位置序号；
                ai----表示第i位置上的号码字符值；
                Wi----示第i位置上的加权因子，其数值依据公式Wi=2^(n-1）(mod 11)计算得出。
                i 18 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1
                Wi 7 9 10 5 8 4 2 1 6 3 7 9 10 5 8 4 2 1

*/
//身份证号合法性验证
//支持15位和18位身份证号
//支持地址编码、出生日期、校验位验证
function IdentityCodeValid(num) {
  num = num.toUpperCase()
  //身份证号码为15位或者18位，15位时全为数字，18位前17位为数字，最后一位是校验位，可能为数字或字符X。
  if (!(/(^\d{15}$)|(^\d{17}([0-9]|X)$)/.test(num))) {
    //alert('输入的身份证号长度不对，或者号码不符合规定！\n15位号码应全为数字，18位号码末位可以为数字或X。');
    //alert('身份证号长度不正确或不符合规定！');
    return false;
  }
  //验证前2位，城市符合
  var aCity={11:"北京",12:"天津",13:"河北",14:"山西",15:"内蒙古",21:"辽宁",22:"吉林",23:"黑龙江 ",31:"上海",32:"江苏",33:"浙江",
    34:"安徽",35:"福建",36:"江西",37:"山东",41:"河南",42:"湖北",43:"湖南",44:"广东",45:"广西",46:"海南",50:"重庆",51:"四川",
    52:"贵州",53:"云南",54:"西藏",61:"陕西",62:"甘肃",63:"青海",64:"宁夏",65:"新疆",71:"台湾",81:"香港",82:"澳门",91:"国外"}
  if(aCity[parseInt(num.substr(0,2))]==null){
    //alert('身份证号不正确或不符合规定！');
    return false
  }
  //alert('城市:'+aCity[parseInt(num.substr(0,2))]);

  //下面分别分析出生日期和校验位
  var len, re; len = num.length
  if (len == 15) {
    re = new RegExp(/^(\d{6})(\d{2})(\d{2})(\d{2})(\d{3})$/)
    var arrSplit = num.match(re);  //检查生日日期是否正确
    var dtmBirth = new Date('19' + arrSplit[2] + '/' + arrSplit[3] + '/' + arrSplit[4])
    var bGoodDay; bGoodDay = (dtmBirth.getYear() == Number(arrSplit[2])) && ((dtmBirth.getMonth() + 1) == Number(arrSplit[3]))
        && (dtmBirth.getDate() == Number(arrSplit[4]));
    if (!bGoodDay) {
      //alert('身份证号的出生日期不对！');
      return false;
    } else { //将15位身份证转成18位 //校验位按照ISO 7064:1983.MOD 11-2的规定生成，X可以认为是数字10。
      var arrInt = new Array(7, 9, 10, 5, 8, 4, 2, 1, 6, 3, 7, 9, 10, 5, 8, 4, 2);
      var arrCh = new Array('1', '0', 'X', '9', '8', '7', '6', '5', '4', '3', '2');
      var nTemp = 0, i;
      num = num.substr(0, 6) + '19' + num.substr(6, num.length - 6)
      for(i = 0; i < 17; i ++) {
        nTemp += num.substr(i, 1) * arrInt[i]
      }
      num += arrCh[nTemp % 11]
      return true;
    }
  }
  if (len == 18) {
    re = new RegExp(/^(\d{6})(\d{4})(\d{2})(\d{2})(\d{3})([0-9]|X)$/)
    var arrSplit = num.match(re)  //检查生日日期是否正确
    var dtmBirth = new Date(arrSplit[2] + "/" + arrSplit[3] + "/" + arrSplit[4])
    var bGoodDay = (dtmBirth.getFullYear() == Number(arrSplit[2]))
        && ((dtmBirth.getMonth() + 1) == Number(arrSplit[3])) && (dtmBirth.getDate() == Number(arrSplit[4]));
    if (!bGoodDay) {
      //alert(dtmBirth.getYear());
      //alert(arrSplit[2]);
      //alert('身份证号的出生日期不对！');
      return false
    } else { //检验18位身份证的校验码是否正确。 //校验位按照ISO 7064:1983.MOD 11-2的规定生成，X可以认为是数字10。
      var valnum
      var arrInt = new Array(7, 9, 10, 5, 8, 4, 2, 1, 6, 3, 7, 9, 10, 5, 8, 4, 2)
      var arrCh = new Array('1', '0', 'X', '9', '8', '7', '6', '5', '4', '3', '2')
      var nTemp = 0, i
      for(i = 0; i < 17; i ++) {
        nTemp += num.substr(i, 1) * arrInt[i]
      }
      valnum = arrCh[nTemp % 11]
      if (valnum != num.substr(17, 1)) {
        //alert('18位身份证的校验码不正确！应该为：' + valnum);
        //alert('18位身份证号的校验码不正确！');
        return false
      }
      return true
    }
  }
  return false
}

/**
 *验证组织机构代码是否合法：组织机构代码为8位数字或者拉丁字母+"-"+1位校验码。
 *验证最后那位校验码是否与根据公式计算的结果相符。
 *编码规则请参看
 *http://wenku.baidu.com/view/d615800216fc700abb68fc35.html
 */
function isValidOrgCode(orgCode) {
  var ret = false
  var codeVal = ["0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K", "L", "M", "N", "O", "P", "Q", "R", "S", "T", "U", "V", "W", "X", "Y", "Z"]
  var intVal = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35]
  var crcs = [3, 7, 9, 10, 5, 8, 4, 2]
  if (!("" == orgCode) && orgCode.length == 10) {
    var sum = 0
    for (var i = 0; i < 8; i++) {
      var codeI = orgCode.substring(i, i + 1);
      var valI = -1;
      for (var j = 0; j < codeVal.length; j++) {
        if (codeI == codeVal[j]) {
          valI = intVal[j]
          break
        }
      }
      sum += valI * crcs[i]
    }
    var crc = 11 - (sum % 11)
    switch (crc) {
      case 10: {
        crc = "X"
        break
      }
      default: {
        break
      }
    }
    //alert("crc="+crc+",inputCrc="+orgCode.substring(9));
    if (crc == orgCode.substring(9)) {
      ret = true
    }
  } else if ("" == orgCode) {
    ret = true
  }
  return ret
}

/**
 *验证营业执照是否合法：营业执照长度须为15位数字，前14位为顺序码，
 *最后一位为根据GB/T 17710 1999(ISO 7064:1993)的混合系统校验位生成算法
 *计算得出。此方法即是根据此算法来验证最后一位校验位是否政正确。如果
 *最后一位校验位不正确，则认为此营业执照号不正确(不符合编码规则)。
 *以下说明来自于网络:
 *我国现行的营业执照上的注册号都是15位的，不存在13位的，从07年开始国
 *家进行了全面的注册号升级就全部都是15位的了，如果你看见的是13位的注
 *册号那肯定是假的。
 *15位数字的含义，代码结构工商注册号由14位数字本体码和1位数字校验码
 *组成，其中本体码从左至右依次为：6位首次登记机关码、8位顺序码。
 * 一、前六位代表的是工商行政管理机关的代码，国家工商行政管理总局用
 * "100000"表示，省级、地市级、区县级登记机关代码分别使用6位行
 * 政区划代码表示。设立在经济技术开发区、高新技术开发区和保税区
 * 的工商行政管理机关（县级或县级以上）或者各类专业分局应由批准
 * 设立的上级机关统一赋予工商行政管理机关代码，并报国家工商行政
 * 管理总局信息化管理部门备案。
 * 二、顺序码是7-14位，顺序码指工商行政管理机关在其管辖范围内按照先
 * 后次序为申请登记注册的市场主体所分配的顺序号。为了便于管理和
 * 赋码，8位顺序码中的第1位（自左至右）采用以下分配规则：
 *　　 1）内资各类企业使用"0"、"1"、"2"、"3"；
 *　　 2）外资企业使用"4"、"5"；
 *　　 3）个体工商户使用"6"、"7"、"8"、"9"。
 * 顺序码是系统根据企业性质情况自动生成的。
 *三、校验码是最后一位，校验码用于检验本体码的正确性
 */
function isValidBusCode(busCode) {
  var ret = false
  if (busCode.length == 15) {
    var sum = 0
    var s = []
    var p = []
    var a = []
    var m = 10
    p[0] = m
    for (var i = 0; i < busCode.length; i++) {
      a[i] = parseInt(busCode.substring(i, i + 1), m)
      s[i] = (p[i] % (m + 1)) + a[i]
      if (0 == s[i] % m) {
        p[i + 1] = 10 * 2
      } else {
        p[i + 1] = (s[i] % m) * 2
      }
    }
    if (1 == (s[14] % m)) {
      //营业执照编号正确!
      ret = true
    } else {
      //营业执照编号错误!
      ret = false
    }
  } else if ("" == busCode) {
    ret = true
  }
  return ret
}

//社会统一信用代码格式判断
function CheckSocialCreditCode(Code) {
  var patrn = /^[0-9A-Z]+$/
  //18位校验及大写校验
  if ((Code.length != 18) || (patrn.test(Code) == false)) {
    return false
  }
  else {
    //统一社会信用代码的每一个值
    var Ancode
    //统一社会信用代码每一个值的权重
    var Ancodevalue
    var total = 0
    //加权因子
    var weightedfactors = [1, 3, 9, 27, 19, 26, 16, 17, 20, 29, 25, 13, 8, 24, 10, 30, 28]
    var str = '0123456789ABCDEFGHJKLMNPQRTUWXY'
    //不用I、O、S、V、Z
    for (var i = 0; i < Code.length - 1; i++) {
      Ancode = Code.substring(i, i + 1)
      Ancodevalue = str.indexOf(Ancode)
      total = total + Ancodevalue * weightedfactors[i]
      //权重与加权因子相乘之和
    }
    var logiccheckcode = 31 - total % 31

    if (logiccheckcode == 31) {
      logiccheckcode = 0
    }
    var Str = "0,1,2,3,4,5,6,7,8,9,A,B,C,D,E,F,G,H,J,K,L,M,N,P,Q,R,T,U,W,X,Y"
    var Array_Str = Str.split(',')
    logiccheckcode = Array_Str[logiccheckcode]

    var checkcode = Code.substring(17, 18)
    if (logiccheckcode != checkcode) {
      return false
    }
    return true
  }
}
